
using System;

public static class Program
{
    private static readonly string[] self_types = {"int8",
                                                   "int16",
                                                   "int32",
                                                   "int64"};
    private static readonly string[,] dependent_types = {{"uint8",     "int8"},
                                                         {"uint16",    "int16"},
                                                         {"uint32",    "int32"},
                                                         {"uint64",    "int64"}};

    private static void w(string a)
    {
        Console.WriteLine(a);
    }

    private static void w()
    {
        Console.WriteLine();
    }

    private static string strcat(params string[] s)
    {
        string r = null;
        for(int i = 0; i < s.Length; i++)
            r += s[i] + "\r\n";
        return r;
    }

    public static void Main()
    {
        w();
        w("\'this file is generated by /osi/root/codegen/unchecked_int/unchecked_int.exe");
        w("\'so change /osi/root/codegen/unchecked_int/unchecked_int.cs instead of this file");
        w();
        w("'why no checked / unchecked in vb.net");
        w();
        w("Imports System.Runtime.CompilerServices");
        w("Imports osi.root.constants");
        w();
        w("Imports int8 = System.SByte");
        w("Imports int16 = System.Int16");
        w("Imports int32 = System.Int32");
        w("Imports int64 = System.Int64");
        w();
        w("Imports uint8 = System.Byte");
        w("Imports uint16 = System.UInt16");
        w("Imports uint32 = System.UInt32");
        w("Imports uint64 = System.UInt64");
        w();
        w("Imports int = System.Int32");
        w("Imports uint = System.UInt32");
        w();
        w("Public Module _unchecked");
        for(int i = 0; i < self_types.Length; i++)
        {
            string c = strcat(
                "    Private Const {0}_1 As {0} = 1",
                "    <Extension()> Private Function inc(ByVal v As {0}, ByVal i As {0}) As {0}",
                "        k_assert(i > 0)",
                "        Try",
                "            If v > max_{0} - i Then",
                "                \'avoid overflow, same as following",
                "                v = v - max_{0} + i + min_{0} - {0}_1",
                "            Else",
                "                v += i",
                "            End If",
                "            Return v",
                "        Catch",
                "            k_assert(False)",
                "            Return 0",
                "        End Try",
                "    End Function", "",
                "    <Extension()> Private Function dec(ByVal v As {0}, ByVal i As {0}) As {0}",
                "        k_assert(i > 0)",
                "        Try",
                "            If v < i + min_{0} Then",
                "                v = v + max_{0} - i - min_{0} + {0}_1",
                "            Else",
                "                v -= i",
                "            End If",
                "            Return v",
                "        Catch",
                "            k_assert(False)",
                "            Return 0",
                "        End Try",
                "    End Function", "",
                "    <Extension()> Private Function inc_min_{0}(ByVal v As {0}) As {0}",
                "        Try",
                "            If v > 0 Then",
                "                v = v + min_{0}",
                "            ElseIf v < 0 Then",
                "                v = v - min_{0}",
                "            Else",
                "                v = min_{0}",
                "            End If",
                "            Return v",
                "        Catch",
                "            k_assert(False)",
                "            Return 0",
                "        End Try",
                "    End Function", "",
                "    <Extension()> Private Function dec_min_{0}(ByVal v As {0}) As {0}",
                "        Try",
                "            If v > 0 Then",
                "                v = v - max_{0} - {0}_1",
                "            ElseIf v < 0 Then",
                "                v = v + max_{0} + {0}_1",
                "            Else",
                "                v = min_{0}",
                "            End If",
                "            Return v",
                "        Catch",
                "            k_assert(False)",
                "            Return 0",
                "        End Try",
                "    End Function", "",
                "    <Extension()> Public Function unchecked_inc(ByVal this As {0}, ByVal that As {0}) As {0}",
                "        If that = 0 Then",
                "            Return this",
                "        ElseIf that = min_{0} Then",
                "            Return this.inc_min_{0}()",
                "        ElseIf that > 0 Then",
                "            Return this.inc(that)",
                "        Else",
                "            k_assert(that < 0 AndAlso that <> min_{0})",
                "            Return this.dec(-that)",
                "        End If",
                "    End Function", "",
                "    <Extension()> Public Function unchecked_dec(ByVal this As {0}, ByVal that As {0}) As {0}",
                "        If that = 0 Then",
                "            Return this",
                "        ElseIf that = min_{0} Then",
                "            Return this.dec_min_{0}()",
                "        ElseIf that > 0 Then",
                "            Return this.dec(that)",
                "        Else",
                "            k_assert(that < 0 AndAlso that <> min_{0})",
                "            Return this.inc(-that)",
                "        End If",
                "    End Function");
            w(string.Format(c, self_types[i]));
        }

        for(int i = 0; i < dependent_types.GetLength(0); i++)
        {
            string c = strcat(
                "    <Extension()> Public Function unchecked_inc(ByVal this As {0}, ByVal that As {0}) As {0}",
                "        Return {1}_{0}(unchecked_inc({0}_{1}(this), {0}_{1}(that)))",
                "    End Function", "",
                "    <Extension()> Public Function unchecked_dec(ByVal this As {0}, ByVal that As {0}) As {0}",
                "        Return {1}_{0}(unchecked_dec({0}_{1}(this), {0}_{1}(that)))",
                "    End Function");
            w(string.Format(c, dependent_types[i, 0], dependent_types[i, 1]));
        }

        w("End Module");
        w();

        {
            string c = strcat(
                "Public Structure unchecked_{0}",
                "    Private ReadOnly v As {0}",
                "    Public Sub New(ByVal v As {0})",
                "        Me.v = v",
                "    End Sub", "",
                "    Public Shared Operator +(ByVal this As unchecked_{0}) As {0}",
                "        Return this.v",
                "    End Operator", "",
                "    Public Shared Widening Operator CType(ByVal this As {0}) As unchecked_{0}",
                "        Return New unchecked_{0}(this)",
                "    End Operator", "",
                "    Public Shared Widening Operator CType(ByVal this As unchecked_{0}) As {0}",
                "        Return this.v",
                "    End Operator", "",
                "    Public Shared Operator +(ByVal this As unchecked_{0}, ByVal that As unchecked_{0}) As unchecked_{0}",
                "        Return this + (+that)",
                "    End Operator", "",
                "    Public Shared Operator +(ByVal this As unchecked_{0}, ByVal that As {0}) As unchecked_{0}",
                "        Return New unchecked_{0}(unchecked_inc(+this, that))",
                "    End Operator", "",
                "    Public Shared Operator +(ByVal this As {0}, ByVal that As unchecked_{0}) As unchecked_{0}",
                "        Return that + this",
                "    End Operator", "",
                "    Public Shared Operator -(ByVal this As unchecked_{0}, ByVal that As unchecked_{0}) As unchecked_{0}",
                "        Return this - (+that)",
                "    End Operator", "",
                "    Public Shared Operator -(ByVal this As unchecked_{0}, ByVal that As {0}) As unchecked_{0}",
                "        Return New unchecked_{0}(unchecked_dec(+this, that))",
                "    End Operator", "",
                "    Public Shared Operator -(ByVal this As {0}, ByVal that As unchecked_{0}) As unchecked_{0}",
                "        Return New unchecked_{0}(this) - that",
                "    End Operator", "",
                "End Structure");
            for(int i = 0; i < self_types.Length; i++)
                w(string.Format(c, self_types[i]));
            for(int i = 0; i < dependent_types.GetLength(0); i++)
                w(string.Format(c, dependent_types[i, 0]));
            w(string.Format(c, "int"));
            w(string.Format(c, "uint"));
        }
    }
}

